JS Class 中的 Static 是什么
今天在看一个有关 JavaScript Class 的 Static 属性的文档,一开始看的英文版本,描述的比较难以理解,然后看中文版,翻译的也比较难以理解。
英文
We can also assign a method to the class as a whole. Such methods are called static.
中文
我们可以把一个方法作为一个整体赋值给类。这样的方法被称为 静态的(static)。
实际上 Static 的概念很简单。在 JavaScript 中,static
是一个关键字,用于定义类的静态方法或静态属性。静态方法和静态属性属于类本身,而不是类的实例。这意味着它们可以直接通过类来调用,而无需实例化类。
静态方法是附加在类本身上的方法,而不是类的实例。它们通常用于执行与类相关的操作,而不依赖于类的实例状态。静态方法可以在类声明中使用 static
关键字进行定义,例如:
class MyClass {
static staticMethod() {
console.log('This is a static method');
}
}
MyClass.staticMethod(); // 调用静态方法
在上面的例子中,staticMethod()
可以直接通过类 MyClass
来调用,而不需要创建 MyClass
的实例。静态方法在类的实例化过程中是不可继承的,它们只能由类本身调用。
类的静态属性也是通过 static
关键字进行定义的,它们是类的共享属性,不属于类的实例。静态属性可以在类声明中直接定义。例如:
class MyClass {
static staticProperty = 'This is a static property';
}
console.log(MyClass.staticProperty); // 访问静态属性
在上面的例子中,staticProperty
是一个静态属性,可以直接通过类 MyClass
来访问。静态属性在类的实例中是不可用的,它们只能通过类本身来访问。
参考
【总结比较】type 和 interface 的区别
在 TypeScript 中,type
和interface
是用来定义类型的关键字,它们有一些区别和特点。
相同点
- 都可以用来定义对象、函数、联合类型等。
- 都可以用来拓展(extends)其他类型。
不同点
type
可以声明基本类型别名、联合类型、交叉类型等复杂类型,而interface
只能用来描述对象结构的类型 [[1]]https://zhuanlan.zhihu.com/p/558315566](https://juejin.cn/post/6844903749501059085)。type
可以使用typeof
获取实例的类型进行赋值,而interface
不支持 [2]。interface
支持声明合并,可以将多个同名的接口进行合并,而type
不支持声明合并 [[1]]https://zhuanlan.zhihu.com/p/558315566](https://juejin.cn/post/6844903749501059085)。
总结
- 一般情况下,如果能用
interface
实现,就优先使用interface
,因为它扩展起来更方便,提示也更友好 [2]。适用于定义对象结构类型和需要进行声明合并的场景。 - 如果需要定义复杂类型,或者需要使用
typeof
获取实例的类型进行赋值,就使用type
[2]。
其它
- 元组类型是 TypeScript 中的一种特殊数据类型,与普通数组不同的是,元组中的每个元素可以具有不同的类型。
参考
- TypeScript 中 type 和 interface 有什么区别? - 知乎
- Typescript 中的 interface 和 type 到底有什么区别 - 掘金
- TS 篇-type 和 interface 的区别 - 掘金
- type 与 interface 的区别,你真的懂了吗? - 掘金
- 元组 · TypeScript 入门教程
【总结】JavaScript 变量作用域和闭包
- Lexical Environment
- 每个运行的函数、代码块或脚本都有一个关联的 Lexical Environment 对象,它用来存储局部变量和函数声明。
- Lexical Environment 有两个组成部分:Environment Record(存储变量)和对外部 Lexical Environment 的引用。
- 函数在执行时会生成一个内部的 Lexical Environment 来存储局部变量和参数。
- 变量
- 变量实际上就是 Lexical Environment 的属性。读取/修改变量就是读取/修改这个对象的属性。
- 函数声明会被立即初始化,但 let/const 变量要到声明后才能读取。
- 块级作用域 - 在 {} 内声明的变量只在块内可见。
- 嵌套函数
- 嵌套函数可以访问外部函数的变量,这使其可以封装外部变量。
- 嵌套函数会通过 Environment 属性记住它被创建的位置,所以它总能访问该位置的外部变量。
- 闭包
- 闭包是可以记住外部变量并访问这些变量的函数。
- JavaScript 中所有函数都是天然的闭包,它们通过 Environment 属性实现。
- 垃圾回收
- 如果嵌套函数被引用,则外部 Lexical Environment 不会被回收。
- 但是如果外部变量没有被嵌套函数使用,引擎会对其进行优化,使其无法在嵌套函数中访问。
- 其他
- 理解 Lexical Environment 和闭包的工作原理可以更好地编写 JavaScript 代码。
- 嵌套函数和闭包在组织代码和封装变量方面很有用。
- 变量优化可能会使开发调试变得困难。
【总结】async 和 await 使用时的注意点
- 使用
await
命令时,最好将其放在try...catch
代码块中处理可能的rejected
结果,或者使用catch()
方法捕获错误。 - 多个
await
命令后面的异步操作如果互不依赖,应该同时触发,可以使用Promise.all()
方法或者使用多个变量并行赋值的方式。 await
命令只能在async
函数中使用,如果在普通函数中使用会报错。如果在普通函数中使用await
,可能会导致异步操作并发执行而不是继发执行,正确的做法是使用for
循环或者reduce()
方法。async
函数可以保留运行堆栈,不会中断函数执行,可以在异步任务运行期间继续执行其他操作。这样可以保留错误堆栈的完整性。
【总结比较】遍历语法的比较
- 最原始的遍历方法是使用
for
循环,但这种写法相对繁琐。 - 数组提供了内置的
forEach
方法,可以简化遍历操作,但无法中途跳出循环。 for...in
循环可以遍历数组的键名,但存在一些缺点,如键名是字符串、会遍历手动添加的其他键和原型链上的键,以及遍历顺序不确定。for...of
循环是一种新的遍历语法,相比其他方法具有以下优点:- 语法简洁,类似于
for...in
循环。 - 不同于
forEach
方法,可以使用break
、continue
和return
来控制循环。 - 提供了统一的遍历数据结构的接口。
- 语法简洁,类似于
使用for...of
循环可以更方便地遍历数组,同时具有灵活控制和统一操作接口的优势。